package com.dmall.opening.up.records.dao.mysql.mybatis.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.session.SqlSessionManager;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

@Configuration
@MapperScan("com.dmall.opening.up.records.dao.mysql.mybatis.mapper")
public class Configurations {

    /**
     * 设置数据源
     */
    @Bean(destroyMethod = "close")
    public DruidDataSource dataSource(@Value("${spring.datasource.driver-class-name}") String driverClassName,
                                      @Value("${spring.datasource.url}") String url,
                                      @Value("${spring.datasource.username}") String username,
                                      @Value("${spring.datasource.password}") String password,
                                      @Value("${spring.datasource.pool.initial.size:1}") Integer initialSize,
                                      @Value("${spring.datasource.pool.min.idle:1}") Integer minIdle,
                                      @Value("${spring.datasource.pool.max.active:5}") Integer maxActive,
                                      @Value("${spring.datasource.pool.max.wait:5000}") Long maxWait) {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setKeepAlive(true);
        dataSource.setDefaultAutoCommit(false);
        dataSource.setInitialSize(initialSize);
        dataSource.setMinIdle(minIdle);
        dataSource.setMaxActive(maxActive);
        dataSource.setMaxWait(maxWait);
        return dataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

    /**
     * 为MYBATIS查询出来的对象自动注入依赖
     */
    @Bean
    public ObjectFactory objectFactory(AutowireCapableBeanFactory beanFactory) {
        return new SpringMybatisObjectFactory(beanFactory);
    }

    /**
     * MYBATIS SqlSessionManager配置
     */
    @Bean
    public SqlSessionManager sqlSessionFactoryBean(DataSource dataSource, ObjectFactory objectFactory) throws Exception {
        SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(dataSource);
        sqlSessionFactory.setObjectFactory(objectFactory);
        sqlSessionFactory.setTypeHandlersPackage("com.dmall.opening.up.records.dao.mysql.mybatis.handler");
        sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mybatis/mappers/*.xml"));
        return SqlSessionManager.newInstance(sqlSessionFactory.getObject());
    }

    /**
     * 事务配置
     */
    @Bean
    public DataSourceTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}
